using ClosedXML.Excel;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using PHMEE.EnergyEfficiency;
using Volo.Abp;
using Volo.Abp.Domain.Repositories;

namespace PHMEE.ConsoleTools.EnergyEfficiency;

public class OvdPortImporter
{
    public const string CommandName = "import-ovd-port";
    
    private IRepository<OvdPort, int> _ovdPortRepository;
    private ILogger<OvdPortImporter> _logger;

    public OvdPortImporter()
    {
    }

    public async Task RunCommandAsync(string[] commandParts, IServiceProvider serviceProvider)
    {
        if (commandParts.Length != 2)
        {
            throw new UserFriendlyException("请提供 OvdPorts 的 Excel 文件路径");
        }
        
        var filePath = commandParts[1];
        
        if (string.IsNullOrWhiteSpace(filePath))
        {
            throw new UserFriendlyException("Excel 文件路径不能为空");
        }
        
        _ovdPortRepository = serviceProvider.GetRequiredService<IRepository<OvdPort, int>>();
        _logger = serviceProvider.GetRequiredService<ILogger<OvdPortImporter>>();
        
        await ImportAsync(filePath);
    }

    private async Task ImportAsync(string filePath)
    {
        // 首先检查 OvdPort 表中是否有数据，如果有数据，则抛出异常，不允许批量导入
        if (await _ovdPortRepository.GetCountAsync() > 0)
        {
            throw new UserFriendlyException("OvdPort 表中已有数据，不允许批量导入");
        }
        
        await using var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
        using var workbook = new XLWorkbook(fileStream);
        
        var worksheet = workbook.Worksheet(1);
        
        var rows = worksheet.RangeUsed()?.RowsUsed().Skip(1) ?? throw new UserFriendlyException("Excel 文件中没有数据");

        List<OvdPort> ovdPorts = [];

        foreach (var row in rows)
        {
            string name = row.Cell("A").GetValue<string>();
            string code = row.Cell("B").GetValue<string>();
            string identifier = row.Cell("C").GetValue<string>();
            
            ovdPorts.Add(new OvdPort(name, code, identifier));
        }

        await _ovdPortRepository.InsertManyAsync(ovdPorts);
        
        _logger.LogInformation("OvdPorts 导入成功，共导入 {0} 条数据", ovdPorts.Count);
    }
}